base_dir = File.expand_path('..', File.dirname(__FILE__))

namespace :docs do

  desc "Generates docs files to preview."
  task :generate do
    require 'erb'
    require 'github/markup'
    template = ERB.new File.read("#{base_dir}/misc/github_template.html.erb")

    Dir.glob("#{base_dir}/**/*.textile").each do |file|
      filename = File.basename(file)
      content = GitHub::Markup.render(file, File.read(file))
      rendered = template.result(binding)
      output = file.gsub(base_dir, "#{base_dir}/misc").gsub(".textile", ".html")
      output_dir = File.dirname(output)
      FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir)
      File.open(output, 'w') {|f| f.write(rendered) }
      puts "Preview rendered to #{output}"
    end
  end

  desc "Convert docs to Nginx wiki format."
  task :convert_to_wiki do
    require 'redcloth'
    require 'nokogiri'
    Dir.glob("#{base_dir}/**/*.textile").each do |file|
      filename = File.basename(file)
      content = File.read(file)

      output      = file.gsub(base_dir, "#{base_dir}/misc").gsub(".textile", ".html")
      output_wiki = file.gsub(base_dir, "#{base_dir}/misc").gsub(".textile", ".wiki")
      output_dir  = File.dirname(output)
      FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir)

      File.open(output, 'w') {|f| f.write(RedCloth.new(content).to_html) }
      File.open(output_wiki, 'w') {|f| f.write(convert_to_wiki_syntax(content)) }
      puts "Wiki converted to #{output_wiki}"
    end
  end

  def convert_to_wiki_syntax(text)
    doc = Nokogiri::HTML(RedCloth.new(text).to_html)
    convert_elements(doc.children.to_a)
  end

  def convert_elements(nodes)
    result = ""
    nodes.each do |node|
      if node.element? && !node.text?
        childrens = node.children.to_a
        unless childrens.empty?
          result += convert_element(convert_elements(childrens), node)
        end
      elsif node.text?
        result += node.text
      end
    end
    result
  end

  def convert_element(text, node)
    tag = node.name
    text ||= ""
    case tag
    when "strong"
      "'''#{text}'''"
    when "b"
      "'''#{text}'''"
    when "em"
      "''#{text}''"
    when "h1"
      "\n= #{text} ="
    when "h2"
      "\n== #{text} =="
    when "h3"
      "\n=== #{text} ==="
    when "h4"
      "\n==== #{text} ===="
    when "h5"
      "\n===== #{text} ====="
    when "h6"
      "\n====== #{text} ======"
    when "p"
      "\n#{text}"
    when "a"
      if node.attributes['href'].value.start_with?("#")
        "[[#{node.attributes['href'].value}|#{text}]]"
      else
        "[#{node.attributes['href'].value} #{text}]"
      end
    when "html"
      text
    when "body"
      text
    when "span"
      text
    else
      "<#{tag}>#{text}</#{tag}>"
    end
  end


end

desc "Run all tests."
task :tests, :executable, :host, :port, :workers, :tests_tmp_dir do |t, args|
  ENV['NGINX_EXEC'] ||= args[:executable] || nil
  ENV['NGINX_HOST'] ||= args[:host] || nil
  ENV['NGINX_PORT'] ||= args[:port] || nil
  ENV['NGINX_WORKERS'] ||= args[:workers] || nil
  ENV['NGINX_TESTS_TMP_DIR'] ||= args[:tests_tmp_dir] || nil

  require 'test/unit'

  Dir.glob('test_*.rb').each do|f|
    test_case = "#{base_dir}/test/#{f}".gsub('.rb', '')
    require test_case
  end
end

begin
  require 'listen'
  require 'jasmine'
  load 'jasmine/tasks/jasmine.rake'

  task "jasmine:require" => "monitor_js"

  task :monitor_js do
    copy_inner_js = Proc.new do |modified, added, removed|
      modified.each do |file|
        destiny_path = File.dirname(file).gsub('misc/js', 'test/tmp/js')
        FileUtils.mkdir_p(destiny_path)
        content = File.read file
        content.gsub!('(function (window, document, undefined) {', '')
        content.gsub!('if (window.PushStream) { return; }', '')
        content.gsub!('})(window, document);', '')
        File.open(File.join(destiny_path, File.basename(file)), 'w') {|f| f.write content }
      end
    end

    copy_inner_js.call([File.expand_path('misc/js/pushstream.js', base_dir)])
    listener = Listen.to(File.expand_path('misc/js', base_dir), :filter => /\.js$/)
    listener.change(&copy_inner_js)
    listener.start(false)
  end
rescue LoadError
  task :jasmine do
    abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
  end
end

begin
  require "jshintrb/jshinttask"
  Jshintrb::JshintTask.new :jshint do |t|
    t.pattern = '../misc/js/pushstream.js'
    t.options = :defaults
  end
rescue LoadError
  task :jshint do
    abort "Jshintrb is not available. In order to run jshint, you must: (sudo) gem install jshintrb"
  end
end
